package uk.co.accolade.clash.app.intellij.vcs;

import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.*;
import uk.co.accolade.clash.core.*;
import uk.co.accolade.clash.app.intellij.IntelliJFileFacade;

import java.util.*;

public class ChangesListener implements ChangeListListener {

    private ChangeListManager changeListManager;
    private IntelliJFileFacade intelliJFileFacade;
    private ChangeHandlerFactory changeHandlerFactory;

    public ChangesListener( ChangeListManager changeListManager,
                            IntelliJFileFacade intelliJFileFacade,
                            ChangeHandlerFactory changeHandlerFactory) {
        this.changeListManager = changeListManager;
        this.intelliJFileFacade = intelliJFileFacade;
        this.changeHandlerFactory = changeHandlerFactory;
    }

    public void changeListAdded( ChangeList changeList ) {
    }

    public void changesRemoved(Collection<Change> changes, ChangeList changeList) {
        handleChangeList();
    }

    public void changeListRemoved( ChangeList changeList ) {
    }

    public void changeListChanged( ChangeList changeList ) {
        handleChangeList();
    }

    public void changeListRenamed( ChangeList changeList, String s ) {
    }

    public void changeListCommentChanged( ChangeList changeList, String s ) {
    }

    public void changesMoved( Collection<Change> changes, ChangeList changeList, ChangeList changeList1 ) {
    }

    public void defaultListChanged(ChangeList changeList, ChangeList changeList1) {
        handleChangeList();
    }

    public void defaultListChanged( ChangeList changeList ) {
        handleChangeList();
    }

    public void unchangedFileStatusChanged() {
    }

    public void changeListUpdateDone() {
    }

    private void handleChangeList() {
        SortedSet<ClashFilePath> fileChanges = flattenChangeLists();
        UserChanges userChanges = new UserChanges( Username.systemUsername(), fileChanges ); 
        changeHandlerFactory.getLocalChangesHandler().handleChanges( userChanges );
    }

    private SortedSet<ClashFilePath> flattenChangeLists() {
        SortedSet<ClashFilePath> flattenedChanges = new TreeSet<ClashFilePath>();
        for( LocalChangeList changeList : changeListManager.getChangeLists() ) {
            for(Change change : changeList.getChanges() ) {
                flattenedChanges.add( localPathForChange( change ) );
            }
        }
        return flattenedChanges;
    }

    private ClashFilePath localPathForChange( Change change ) {
        FilePath filePath = ChangesUtil.getBeforePath( change );
        if( filePath == null ) {
            filePath = ChangesUtil.getFilePath( change );
        }
        return intelliJFileFacade.getFilename( filePath.getPath() );
    }
}
